<template>
  <div style="position: relative">
    <div :class="`chart-wrapper ${className}`">
      <div
        ref="wrapper"
        :style="`position: relative;max-height: ${maxHeight}px;`"
      >
        <div :id="id" :class="`heatmap-chart`"></div>
      </div>
      <div
        ref="xaxis"
        :id="id + '-x'"
        :class="`heatmap-chart-x`"
        :style="`transform: translateX(${sx}px)`"
      ></div>
    </div>

    <div ref="yaxis" class="y-axis-label">
      <div class="heatmap-chart-y" :style="`transform: translateY(${sy}px)`">
        <option
          v-for="(yl, index) in yAxisLabels"
          :key="yl + index"
          class="y-axis-label-text"
          :title="yl"
          :style="`width: ${yAxisLabelWidth}px;height: ${yAxisLabelHeight}px;line-height: ${
            yAxisLabelHeight - 2
          }px`"
        >
          {{ yl }}
        </option>
      </div>
    </div>

    <m-tooltip :show="tip" :no-arrow="true" class-name="c-heatmap-tip">
      <div class="heatmap-tip">
        <div>{{ tipContent.x_dim }}</div>
        <div>
          <span
            v-show="tipContent.color"
            :style="`display: inline-block;  width: 10px; height: 10px; border-radius: 2px; background: ${tipContent.color}`"
          ></span>
          {{ tipContent.y_dim }}: {{ tipContent.value }}
        </div>
      </div>
    </m-tooltip>
    <!-- custom-horizontal-scrollbar-->
    <!-- <div class="custom-horizontal-scrollbar" ref="horizontal">
      <div
        class="custom-horizontal-indicator"
        :style="{ width: indicator }"
      ></div>
    </div> -->
    <!-- custom-horizontal-scrollbar-->
    <!-- <div class="custom-vertical-scrollbar" ref="vertical">
      <div
        class="custom-vertical-indicator"
        :style="{ height: indicator }"
      ></div>
    </div> -->
  </div>
</template>

<script>
import Heatmap, { d3 } from "./Heatmap.js";
import { getTextWith, debounce } from "../../utils";
import MTooltip from "../../components/MTooltip/index.vue";
import BScroll from "@better-scroll/core";
import ScrollBar from "@better-scroll/scroll-bar";
import MouseWheel from "@better-scroll/mouse-wheel";
BScroll.use(ScrollBar);
BScroll.use(MouseWheel);

export default {
  name: "CHeatmap",
  components: { MTooltip },
  props: {
    className: {
      type: String,
      default: "",
    },
    id: {
      type: String,
      default: "c-heatmap",
    },
    htData: {
      type: Array,
      default: () => [],
    },
    // startDate: {
    //   type: String,
    //   default: "",
    // },
    // endDate: {
    //   type: String,
    //   default: "",
    // },
    options: {
      type: Object,
      default: () => ({}),
    },
    colors: {
      type: Array,
      default: ["#FFFFDD", "#3E9583", "#1F2D86"],
    },
    maxHeight: {
      type: Number,
      default: 768,
    },
  },
  data() {
    return {
      chart: null,
      tip: false,
      tipContent: "",
      yAxisLabels: [],
      yAxisLabelWidth: 15,
      yAxisLabelHeight: 14,
      // indicator: "20px",
      sx: 0,
      sy: 0,
    };
  },
  watch: {
    htData: {
      handler(htData) {
        this.yAxisLabels = Array.from(new Set(htData.map((d) => d.y_dim)));

        // const longestOne = this.yAxisLabels.reduce((a, b) =>
        //   a.length > b.length ? a : b
        // );
        // const more = getTextWith(longestOne) - this.yAxisLabelWidth;
        // this.yAxisLabelWidth =
        //   more > 0 ? more + this.yAxisLabelWidth : this.yAxisLabelWidth;
        // this.chart.update(htData, { left: more > 0 ? more : 0 });

        this.chart.update(htData, this.options);
        this.$nextTick(() => {
          this.refreshBscroll();
        });
      },
      deep: true,
    },
    startDate(n, o) {
      if (this.chart) {
        this.chart._options.start = n;
      }
    },
    endDate(n, o) {
      if (this.chart) {
        this.chart._options.end = n;
      }
    },
  },
  mounted() {
    this.initChart();
    this.initBscroll();
  },
  beforeDestroy() {
    this.chart.destroy();
    this.chart = null;
  },
  methods: {
    initChart() {
      // 初始化
      this.chart = new Heatmap(`#${this.id}`, {
        xAxisDom: `#${this.id}-x`,
        // start: new Date(this.startDate),
        // end: new Date(this.endDate),
        colors: this.colors,
        fontSize: 13,
        radius: 1,
        mouseover: (event, d) => {
          this.tip = true;
          //   this.tipContent = d.value;
        },
        mousemove: (event, d) => {
          //   this.tipContent = d.y_dim + "\n" + d.x_dim + ": " + d.value;
          this.tipContent = d;
        },
        mouseleave: (event, d) => {
          this.tip = false;
        },
        drawEnd: (yDim) => {
          this.yAxisLabels = yDim;
        },
        ...this.options,
      });
      // this.yAxisLabelHeight = this.chart._options.size;
      this.yAxisLabelHeight = this.chart._options.size;
      // this.yAxisLabelWidth = (this.chart._options.dateFormat.length / 2) * 5;
      this.yAxisLabelWidth =
        this.chart._options.left +
        (this.chart._options.dateFormat.length / 2) * 5;

      this.chart.update(this.htData);
      this.yAxisLabels = Array.from(new Set(this.htData.map((d) => d.y_dim)));
    },
    initBscroll() {
      this.scroll = new BScroll(this.$refs.wrapper, {
        scrollX: true,
        scrollY: true,
        // click: false,
        bounce: false,
        mouseWheel: true,
        freeScroll: false,
        probeType: 3,
        scrollbar: {
          // customElements: [this.$refs.horizontal, this.$refs.vertical],
          fade: true,
          interactive: true,
          scrollbarTrackClickable: false,
        },
      });
      this.scroll.on(
        "scroll",
        debounce((position) => {
          // console.log(position.x, position.y, this);
          this.sx = position.x;
          this.sy = position.y;
        })
      );
    },
    refreshBscroll() {
      // this.indicator =
      //   (this.$refs.wrapper.getBoundingClientRect().width /
      //     this.$refs.wrapper.firstChild.getBoundingClientRect().width) *
      //     100 +
      //   "px";
      this.$nextTick(() => {
        this.scroll.refresh();
      });
    },
  },
};
</script>

<style lang="scss">
.chart-wrapper {
  width: 100%;
  // max-height: 768px;
  overflow: hidden;
  .heatmap-chart {
    // position: relative;
    // overflow: hidden;
    margin: 0;
    width: fit-content;
  }
  .heatmap-chart-x {
    background-color: #fff;
    position: relative;
    width: fit-content;
    z-index: 1;
  }
}

.c-heatmap-tip {
  width: fit-content;
  height: auto;
}

.y-axis-label {
  position: absolute;
  left: 0;
  top: 0;
  flex-direction: column;
  align-items: flex-end;
  gap: 0;
  background: #fff;
  height: calc(100% - 19px);
  overflow: hidden;
  &-text {
    font-size: 12px;
    line-height: 1;
    height: min-content;
    padding: 0;
    margin: 0;
    text-align: right;
    padding-right: 2px;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
    cursor: default;
  }
  .heatmap-chart-y {
    background-color: #fff;
    position: relative;
    width: fit-content;
    z-index: 1;
  }
}

.custom-horizontal-scrollbar {
  // position: absolute;
  // left: 50%;
  // bottom: 10px;
  width: 100px;
  // width: 50%;
  height: 7px;
  // border-radius: 6px;
  // transform: translateX(50%) translateZ(0);
  background-color: #dfdfdf;
  .custom-horizontal-indicator {
    height: 100%;
    // width: 50%;
    width: 20px;
    // border-radius: 6px;
    background-color: #7d7a7b;
  }
}

.custom-vertical-scrollbar {
  // position: absolute;
  // left: 50%;
  // bottom: 10px;
  width: 7px;
  // width: 50%;
  height: 100px;
  // border-radius: 6px;
  // transform: translateX(50%) translateZ(0);
  background-color: #dfdfdf;
  .custom-vertical-indicator {
    height: 20px;
    // width: 50%;
    width: 100%;
    // border-radius: 6px;
    background-color: #7d7a7b;
  }
}
</style>
